package com.med.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.med.interceptor.AuthInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.converter.MessageConverter;
import org.springframework.messaging.converter.StringMessageConverter;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * Project:internet-based-healthcare
 * Package:com.med.config
 *
 * @Description:
 * @Author:其一
 * @CreateTime: 2025-08-25-08-58
 */
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    @Autowired
    private AuthInterceptor authInterceptor;
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/chat/ws")
                .setAllowedOriginPatterns("*")
                .addInterceptors(authInterceptor)
                .withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        // 发送消息前缀
        config.setApplicationDestinationPrefixes("/app");
        // 推送消息频道
        config.enableSimpleBroker(
                "/doctor/msg",   // 医生接收：/doctor/msg/医生ID
                "/user/doctor",  // 用户接收医生消息：/user/doctor/用户ID
                "/customer/msg", // 客服接收：/customer/msg/客服ID
                "/user/customer" // 用户接收客服消息：/user/customer/用户ID
        );
    }

    @Override
    public boolean configureMessageConverters(List<MessageConverter> messageConverters) {
// 1. 清空默认转换器（避免默认配置冲突）
        messageConverters.clear();

        // 2. 添加字符串转换器（处理纯文本消息，可选）
        StringMessageConverter stringConverter = new StringMessageConverter();
        messageConverters.add(stringConverter);

        // 3. 添加JSON转换器（核心：处理DoctorMessage/CustomerMessage等实体类）
        MappingJackson2MessageConverter jacksonConverter = new MappingJackson2MessageConverter();
        // 自定义Jackson配置（解决日期格式、空值、字段匹配问题）
        ObjectMapper objectMapper = new ObjectMapper()
                // 1. 日期格式统一（适配实体类中的@JsonFormat）
                .registerModule(getJava8DateTimeModule())
                // 2. 忽略未知字段（避免前端传多余字段导致反序列化失败）
                .configure(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
                // 3. 空值字段不序列化（减少传输数据量）
                .setSerializationInclusion(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL);

        jacksonConverter.setObjectMapper(objectMapper);
        messageConverters.add(jacksonConverter);

        // 4. 返回true表示使用自定义转换器，false表示叠加默认转换器
        return true;
    }


    /**
     * 配置Java8日期类型（LocalDateTime）的序列化/反序列化规则
     * 解决LocalDateTime与JSON字符串的转换问题
     */
    private SimpleModule getJava8DateTimeModule() {
        SimpleModule module = new SimpleModule();
        // 日期格式化模板（与实体类@JsonFormat一致）
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 序列化：LocalDateTime → String（后端发消息给前端时）
        module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
        // 反序列化：String → LocalDateTime（前端发消息给后端时）
        module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));

        return module;
    }

}
